# !/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
@作者 杨阳
@时间 2018-08-03 16:06:14
@说明 t_scheduler表对应的routes文件
@注意事项
"""
import json
import threading
import traceback

from flask import Blueprint, request

from model.TSchedulerModel import TSchedulerModel, execute_sql, ApschedulerJobs
from util import LogUtil, SchedulerUtil
from util.JsonUtil import classToDict, JsonEncoder
from util.SessionUtil import Mast_be_login_decorator
from util.ThreadPluginsInitUtil import scheduler_obj

scheduler = Blueprint('scheduler', __name__, url_prefix='/scheduler')


@scheduler.route("/jobgrid/", methods=["POST"])
@Mast_be_login_decorator
def job_grid():
    """
    查询调度中的定时任务列表
    :return:
    """
    return ApschedulerJobs.query_entity_grid()


@scheduler.route("/grid/", methods=["POST"])
@Mast_be_login_decorator
def entity_grid():
    """
    查询实体类表格形式的数据
    :return: json 字符串
    """
    current_page = request.form.get("current_page")
    group_id = request.form.get("group_id")
    search_comment = request.form.get("search_comment")
    search_status = request.form.get("search_status")
    search_interval = request.form.get("search_interval")
    search_execute_method = request.form.get("search_execute_method")
    search_start_create_time = request.form.get("search_start_create_time")
    search_end_create_time = request.form.get("search_end_create_time")
    return TSchedulerModel.query_entity_grid(group_id, search_comment, search_status, search_interval,
                                             search_execute_method, search_start_create_time, search_end_create_time,
                                             current_page)


@scheduler.route("/save/", methods=["POST"])
@Mast_be_login_decorator
def save_entity():
    """
    保存实体
    :return: json 字符串
    """
    id = request.form.get("id")
    comment = request.form.get("comment")
    status = request.form.get("status")
    interval = request.form.get("interval")
    execute_method = request.form.get("execute_method")
    group_id = request.form.get("group_id")
    if id and id != '':
        return TSchedulerModel.update_entity(id, comment, interval, execute_method)
    else:
        return TSchedulerModel.add_entity(comment, status, interval, execute_method, group_id)


@scheduler.route("/delete/<id>", methods=["DELETE"])
@Mast_be_login_decorator
def delete_entity(id):
    """
    根据id删除实体类
    :return: json 字符串
    """
    return TSchedulerModel.delete_entity_byId(id)


@scheduler.route("/stopDeath/", methods=["POST"])
@Mast_be_login_decorator
def stopDeath():
    """
    将任务从调度中移除
    :return:
    """
    try:
        id = request.form.get("id")
        model = TSchedulerModel.get_entity_byId(id)
        model.is_enable = 0
        model.status = 0
        model.error_msg = ''
        TSchedulerModel.update(model)

        sc = scheduler_obj.get_job(id)
        if sc is not None:
            sc.remove()
        result = {"success": True, "msg": "停用定时任务成功!"}
    except Exception as e:
        LogUtil.info("停用定时任务异常！！{}".format(e))
        result = {"success": False, "msg": "停用定时任务失败，请重试!"}
    finally:
        pass
    return json.dumps(result)


@scheduler.route("/get/<id>", methods=["GET"])
@Mast_be_login_decorator
def get_entity_byId(id):
    """
    根据id获得实体
    :return: json 字符串
    """
    scheduler = TSchedulerModel.get_entity_byId(id)
    result = {"success": True, "scheduler": classToDict(scheduler)}
    return json.dumps(result, cls=JsonEncoder)


@scheduler.route("/instantDeath/", methods=["POST"])
def instantDeath():
    """
    立即执行某个定时任务
    状态： 执行状态： 0.未执行 1.执行中 2.执行成功 3.执行失败
    :return:
    """
    try:
        id = request.form.get("id")

        # 开始执行前先更新数据库
        model = TSchedulerModel.get_entity_byId(id)
        model.status = 1
        TSchedulerModel.update(model)
        LogUtil.info("开始调用方法：{}".format(model.execute_method))

        # 这里启动一个线程，因为定时任务一般比较耗时，所以启动一个线程去搞他
        thd = schedulerThread(model.execute_method)
        thd.start()

        # 执行成功
        model.status = 2
        TSchedulerModel.update(model)

        return json.dumps({"success": True, "msg": "执行成功!!"})
    except Exception as es:

        LogUtil.debug("执行定时任务异常:{}".format(es))

        # 执行失败，同时从启用状态变成未启用，将错误信息保存在error_msg中，以便查找问题
        model.status = 3
        model.is_enable = 0
        model.error_msg = traceback.format_exc()
        TSchedulerModel.update(model)

        return json.dumps({"success": False, "msg": "执行失败!!"})


@scheduler.route("/startscheduler/", methods=["POST"])
def startscheduler():
    """
    将定时任务加入调试中，按照设定的表达式执行
    :return:
    """
    try:
        obj_id = request.form.get("id")
        model = TSchedulerModel.get_entity_byId(obj_id)
        interval = model.interval
        LogUtil.info("定时任务表达式：{}".format(interval))
        interval_json = json.loads(interval)
        interval_type = interval_json["type"]
        LogUtil.info("任务类型：{}".format(interval_type))
        params = {}
        if "cron" == interval_type:
            for k in interval_json:
                value = interval_json[k]
                LogUtil.info("键：{}======>值：{}".format(k, value))
                if k != "type":
                    params[k] = value

            job = scheduler_obj.get_job(obj_id)
            if job != None:
                LogUtil.info("定时任务：{}已经存在，先移除再添加!!!".format(job))
                job.remove()
                job = scheduler_obj.get_job(obj_id)
                LogUtil.info("删除以后还有没有了!!!!{}".format(job))

            scheduler_obj.add_job(func=SchedulerUtil.execute_methods(model.execute_method),
                                  trigger="cron",
                                  id=obj_id,
                                  **params)

            model.is_enable = 1
            TSchedulerModel.update(model)

            result = {"success": True, "msg": "定时任务开始调试!"}
    except Exception as es:
        LogUtil.info(traceback.format_exc())

        result = {"success": False, "msg": "定时任务调试失败，请重试!"}
    return json.dumps(result)


def scheduler_print():
    print("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")


class schedulerThread(threading.Thread):

    def __init__(self, method_name):
        # 下面这句一定要有，否则会报错题
        threading.Thread.__init__(self)
        self.method_name = method_name

    def run(self):
        print("启动线程.....")
        SchedulerUtil.execute_methods(self.method_name)
        print("执行完毕.....")
